package com.hunit.mqtt_dome.emqx;

import com.hunit.mqtt_dome.properties.MqttProperties;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

/**
 * @Description : MQTT接受服务的客户端
 * @Author : Sherlock
 * @Date : 2023/8/1 16:26
 */
@Component
public class MqttAcceptClient {

    private static final Logger logger = LoggerFactory.getLogger(MqttAcceptClient.class);

    @Autowired
    @Lazy
    private MqttAcceptCallback mqttAcceptCallback;

    @Autowired
    private MqttProperties mqttProperties;

    private MqttClient mqttClient;
    private boolean connected = false;

    /**
     * 客户端连接
     * 
     * @return 是否连接成功
     */
    public boolean connect() {
        // 如果已连接，直接返回成功
        if (connected && mqttClient != null && mqttClient.isConnected()) {
            return true;
        }
        
        try {
            mqttClient = new MqttClient(mqttProperties.getHostUrl(), mqttProperties.getClientId(),
                    new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setUserName(mqttProperties.getUsername());
            options.setPassword(mqttProperties.getPassword().toCharArray());
            options.setConnectionTimeout(mqttProperties.getTimeout());
            options.setKeepAliveInterval(mqttProperties.getKeepAlive());
            options.setAutomaticReconnect(mqttProperties.getReconnect());
            options.setCleanSession(mqttProperties.getCleanSession());
            
            // 设置回调
            mqttClient.setCallback(mqttAcceptCallback);
            mqttClient.connect(options);
            connected = true;
            logger.info("MQTT接收客户端连接成功，clientId: {}", mqttProperties.getClientId());
            return true;
        } catch (Exception e) {
            connected = false;
            logger.error("MQTT接收客户端连接失败，错误信息: {}", e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 重新连接
     * 
     * @return 是否重连成功
     */
    public boolean reconnection() {
        connected = false;
        try {
            if (mqttClient != null) {
                mqttClient.connect();
                connected = true;
                logger.info("MQTT接收客户端重连成功");
                return true;
            } else {
                logger.error("MQTT接收客户端实例为空，无法重连");
                return connect(); // 尝试重新创建连接
            }
        } catch (MqttException e) {
            logger.error("MQTT接收客户端重连失败，错误信息: {}", e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 订阅某个主题
     *
     * @param topic 主题
     * @param qos   连接方式
     * @return 是否订阅成功
     */
    public boolean subscribe(String topic, int qos) {
        logger.info("========================【开始订阅主题:" + topic + "】========================");
        
        // 检查连接状态，如果未连接则先连接
        if (!connected || mqttClient == null || !mqttClient.isConnected()) {
            if (!connect()) {
                logger.error("MQTT接收客户端未连接，无法订阅主题");
                return false;
            }
        }
        
        try {
            mqttClient.subscribe(topic, qos);
            logger.info("主题订阅成功: {}", topic);
            return true;
        } catch (MqttException e) {
            logger.error("主题订阅失败: {}, 错误信息: {}", topic, e.getMessage());
            e.printStackTrace();
            connected = false; // 标记连接状态为断开
            return false;
        }
    }

    /**
     * 取消订阅某个主题
     *
     * @param topic 主题
     * @return 是否取消订阅成功
     */
    public boolean unsubscribe(String topic) {
        logger.info("========================【取消订阅主题:" + topic + "】========================");
        
        if (!connected || mqttClient == null || !mqttClient.isConnected()) {
            logger.error("MQTT接收客户端未连接，无法取消订阅主题");
            return false;
        }
        
        try {
            mqttClient.unsubscribe(topic);
            logger.info("取消订阅成功: {}", topic);
            return true;
        } catch (MqttException e) {
            logger.error("取消订阅失败: {}, 错误信息: {}", topic, e.getMessage());
            e.printStackTrace();
            connected = false; // 可能的连接问题，标记为断开
            return false;
        }
    }
    
    /**
     * 断开连接并释放资源
     */
    public void disconnect() {
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                mqttClient.disconnect();
                mqttClient.close();
                connected = false;
                logger.info("MQTT接收客户端已断开连接");
            }
        } catch (MqttException e) {
            logger.error("MQTT接收客户端断开连接失败，错误信息: {}", e.getMessage());
            e.printStackTrace();
        }
    }
}
